package com.hyts.sftp;

import com.hyts.sftp.bean.SFTPSubject;
import com.hyts.sftp.error.SFTPError;
import com.hyts.sftp.monitor.SFTPProgressMonitor;
import com.hyts.sftp.util.SFTPClient;
import com.jcraft.jsch.ChannelSftp;
import org.apache.commons.lang3.StringUtils;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

/**
 * project-name:coffice-toolbox
 * package-name:com.hyts.sftp
 * author:Libo/Alex
 * create-date:2019-06-18 21:26
 * copyright:libo-hyts-github
 * email:libo2dev@aliyun.com
 * description:此类主要用于:
 */
public class SFTP {

    private final static String sftpHost = "192.168.118.129";
    private final static int sftpPort = 22;
    private final static String sftpUserName = "sftpuser";
    private final static String sftpPassword = "19920508";

    private static SFTPClient getSFTPClient() {
        return new SFTPClient(new SFTPSubject(sftpHost, sftpPort, sftpUserName, sftpPassword));
    }

    /*************************************upload*************************************/
    public static void uploadOverwrite(String localFilePath, String remotePath) {
        SFTPClient client = getSFTPClient();
        try {
            SFTPSubject params = buildSFTPSubject(localFilePath, remotePath);
            client.upload(params, ChannelSftp.OVERWRITE);
        } catch (SFTPError e) {
            e.printStackTrace();
        } finally {
            client.close();
        }
    }

    public static void uploadAppend(String localFilePath, String remotePath) {
        SFTPClient client = getSFTPClient();
        try {
            SFTPSubject params = buildSFTPSubject(localFilePath, remotePath);
            client.upload(params, ChannelSftp.APPEND);
        } catch (SFTPError e) {
            e.printStackTrace();
        } finally {
            client.close();
        }
    }

    public static void uploadResume(String localFilePath, String remotePath) {
        SFTPClient client = getSFTPClient();
        try {
            SFTPSubject params = buildSFTPSubject(localFilePath, remotePath);
            client.upload(params, ChannelSftp.RESUME);
        } catch (SFTPError e) {
            e.printStackTrace();
        } finally {
            client.close();
        }
    }

    public static void uploadOverwriteWithTimerMonitor(String localFilePath, String remotePath) {
        SFTPClient client = getSFTPClient();
        try {
            SFTPSubject params = buildSFTPSubject(localFilePath, remotePath);
            client.upload(params, ChannelSftp.OVERWRITE, new SFTPProgressMonitor());
        } catch (SFTPError e) {
            e.printStackTrace();
        } finally {
            client.close();
        }
    }

    public static void uploadAppendWithTimerMonitor(String localFilePath, String remotePath) {
        SFTPClient client = getSFTPClient();
        try {
            SFTPSubject params = buildSFTPSubject(localFilePath, remotePath);
            client.upload(params, ChannelSftp.APPEND, new SFTPProgressMonitor());
        } catch (SFTPError e) {
            e.printStackTrace();
        } finally {
            client.close();
        }
    }

    public static void uploadResumeWithTimerMonitor(String localFilePath, String remotePath) {
        SFTPClient client = getSFTPClient();
        try {
            SFTPSubject params = buildSFTPSubject(localFilePath, remotePath);
            client.upload(params, ChannelSftp.RESUME, new SFTPProgressMonitor());
        } catch (SFTPError e) {
            e.printStackTrace();
        } finally {
            client.close();
        }
    }

    public static void uploadOverwrite(InputStream src, String remotePath) {
        SFTPClient client = getSFTPClient();
        try {
            SFTPSubject params = buildSFTPSubject(null, remotePath);
            client.upload(params, ChannelSftp.OVERWRITE, src);
        } catch (SFTPError e) {
            e.printStackTrace();
        } finally {
            client.close();
        }
    }

    public static void uploadAppend(InputStream src, String remotePath) {
        SFTPClient client = getSFTPClient();
        try {
            SFTPSubject params = buildSFTPSubject(null, remotePath);
            client.upload(params, ChannelSftp.APPEND, src);
        } catch (SFTPError e) {
            e.printStackTrace();
        } finally {
            client.close();
        }
    }

    public static void uploadResume(InputStream src, String remotePath) {
        SFTPClient client = getSFTPClient();
        try {
            SFTPSubject params = buildSFTPSubject(null, remotePath);
            client.upload(params, ChannelSftp.RESUME, src);
        } catch (SFTPError e) {
            e.printStackTrace();
        } finally {
            client.close();
        }
    }

    public static void uploadOverwrite(InputStream src, int bufferSize, String remotePath) {
        SFTPClient client = getSFTPClient();
        try {
            SFTPSubject params = buildSFTPSubject(null, remotePath);
            client.upload(params, ChannelSftp.OVERWRITE, src, bufferSize);
        } catch (SFTPError e) {
            e.printStackTrace();
        } finally {
            client.close();
        }
    }

    public static void uploadAppend(InputStream src, int bufferSize, String remotePath) {
        SFTPClient client = getSFTPClient();
        try {
            SFTPSubject params = buildSFTPSubject(null, remotePath);
            client.upload(params, ChannelSftp.APPEND, src, bufferSize);
        } catch (SFTPError e) {
            e.printStackTrace();
        } finally {
            client.close();
        }
    }

    public static void uploadResume(InputStream src, int bufferSize, String remotePath) {
        SFTPClient client = getSFTPClient();
        try {
            SFTPSubject params = buildSFTPSubject(null, remotePath);
            client.upload(params, ChannelSftp.RESUME, src, bufferSize);
        } catch (SFTPError e) {
            e.printStackTrace();
        } finally {
            client.close();
        }
    }

    /*************************************download*************************************/
    public static void download(String remotePath, String localFilePath) {
        SFTPClient client = getSFTPClient();
        try {
            SFTPSubject params = buildSFTPSubject(localFilePath, remotePath);
            client.download(params);
        } catch (SFTPError e) {
            e.printStackTrace();
        } finally {
            client.close();
        }
    }

    public static void downloadWithTimerMonitor(String remotePath, String localFilePath) {
        SFTPClient client = getSFTPClient();
        try {
            SFTPSubject params = buildSFTPSubject(localFilePath, remotePath);
            client.download(params, new SFTPProgressMonitor());
        } catch (SFTPError e) {
            e.printStackTrace();
        } finally {
            client.close();
        }
    }

    public static void download(OutputStream os, String remotePath) {
        SFTPClient client = getSFTPClient();
        try {
            SFTPSubject params = buildSFTPSubject(null, remotePath);
            client.download(params, os);
        } catch (SFTPError e) {
            e.printStackTrace();
        } finally {
            client.close();
        }
    }

    public static void downloadWithTimerMonitor(OutputStream os, String remotePath) {
        SFTPClient client = getSFTPClient();
        try {
            SFTPSubject params = buildSFTPSubject(null, remotePath);
            client.download(params, new SFTPProgressMonitor(), os);
        } catch (SFTPError e) {
            e.printStackTrace();
        } finally {
            client.close();
        }
    }


    /**
     * 该方法使用时会出现异常：java.io.IOException: Pipe closed
     * 原因是在 finally 中执行了 client.close();
     *
     * @param remotePath
     * @return
     */
    @Deprecated
    public static InputStream download2InputStream(String remotePath) {
        SFTPClient client = getSFTPClient();
        try {
            SFTPSubject params = new SFTPSubject();
            params.setRemoteFilePath(remotePath);
            return client.download2InputStream(params);
        } catch (SFTPError e) {
            e.printStackTrace();
        } finally {
            client.close();
        }

        return null;
    }

    /*************************************other*************************************/
    public static List<String> ls(String remotePath) {
        SFTPClient client = getSFTPClient();
        try {
            if (StringUtils.isEmpty(remotePath.trim())) {
                return null;
            }

            return client.ls(remotePath);
        } catch (SFTPError e) {
            e.printStackTrace();
        } finally {
            client.close();
        }

        return null;
    }

    /*************************************private*************************************/
    /*
     * 构造SFTPSubject参数
     *
     * @param remotePath
     * @param localFilePath
     * @return
     */
    private static SFTPSubject buildSFTPSubject(String localFilePath, String remotePath) {
        SFTPSubject params = new SFTPSubject();
        if (StringUtils.isNotEmpty(localFilePath)) {
            params.setLocalFilePath(localFilePath);
        }
        if (StringUtils.isNotEmpty(remotePath)) {
            params.setRemoteFilePath(remotePath);
        }

        return params;
    }
}


